import mysql.connector
from elasticsearch import Elasticsearch
import logging
from datetime import datetime
import json

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def validate_sync():
    # 数据库配置
    mysql_config = {
        'host': 'localhost',
        'user': 'journeo',
        'password': 'journeo',
        'database': 'journeo'
    }

    # Elasticsearch配置
    es = Elasticsearch(['http://localhost:9200'])

    try:
        # 连接MySQL
        mysql_conn = mysql.connector.connect(**mysql_config)
        cursor = mysql_conn.cursor(dictionary=True)

        # 1. 检查记录总数
        cursor.execute("SELECT COUNT(*) as count FROM attractions")
        mysql_count = cursor.fetchone()['count']

        es_count = es.count(index='attractions')['count']

        logger.info(f"MySQL记录总数: {mysql_count}")
        logger.info(f"Elasticsearch记录总数: {es_count}")

        if mysql_count != es_count:
            logger.warning(f"数据总数不匹配！MySQL: {mysql_count}, ES: {es_count}")

        # 2. 抽样检查部分记录
        cursor.execute("""
            SELECT * FROM attractions 
            ORDER BY RAND() 
            LIMIT 5
        """)
        sample_records = cursor.fetchall()

        # 字段名映射（MySQL列名到ES字段名的映射）
        field_mapping = {
            'AttractionId': 'attractionId',
            'RegionId': 'regionId',
            'Name': 'name',
            'Description': 'description',
            'Address': 'address',
            'Image': 'image',
            'Latitude': 'latitude',
            'Longitude': 'longitude',
            'PriceRange': 'priceRange',
            'OpeningHours': 'openingHours',
            'AttractionRating': 'attractionRating',
            'RecommendedVisitTime': 'recommendedVisitTime',
            'RecommendedVisitSeason': 'recommendedVisitSeason',
        }

        for record in sample_records:
            attraction_id = record['AttractionId']

            # 获取ES中的对应记录
            try:
                es_doc = es.get(index='attractions', id=str(attraction_id))['_source']

                # 检查所有字段
                for mysql_field, es_field in field_mapping.items():
                    mysql_value = record[mysql_field]
                    es_value = es_doc.get(es_field)

                    # 处理数值类型字段
                    if mysql_field in ['Latitude', 'Longitude', 'AttractionRating']:
                        if mysql_value is not None:
                            mysql_value = float(mysql_value)

                    if mysql_value != es_value:
                        logger.warning(f"记录 {attraction_id} 的 {mysql_field} 字段不匹配")
                        logger.warning(f"MySQL值: {mysql_value}")
                        logger.warning(f"ES值: {es_value}")
                        logger.warning(f"MySQL值类型: {type(mysql_value)}")
                        logger.warning(f"ES值类型: {type(es_value)}")

                logger.info(f"记录 {attraction_id} 验证完成")

            except Exception as e:
                logger.error(f"验证记录 {attraction_id} 时出错: {str(e)}")

        # 3. 检查最新更新时间
        cursor.execute("SELECT MAX(UpdatedAt) as latest FROM attractions")
        mysql_latest = cursor.fetchone()['latest']

        es_latest_query = {
            "size": 1,
            "sort": [{"updatedAt": "desc"}]
        }
        es_latest = es.search(index='attractions', body=es_latest_query)
        es_latest_date = es_latest['hits']['hits'][0]['_source']['updatedAt']

        logger.info(f"MySQL最新更新时间: {mysql_latest}")
        logger.info(f"ES最新更新时间: {es_latest_date}")

    except Exception as e:
        logger.error(f"验证过程出错: {str(e)}")
        raise
    finally:
        if 'cursor' in locals():
            cursor.close()
        if 'mysql_conn' in locals():
            mysql_conn.close()


if __name__ == "__main__":
    validate_sync()